﻿using UnityEngine;

namespace UnityTouchTable.Example
{
    /// <summary>
    /// 子内容节点基类
    /// </summary>
    [RequireComponent(typeof(BoxCollider2D), typeof(RelativeJoint2D))]
    public class SubContentNodeBase : MonoBehaviour
    {
        #region Field
        /// <summary>
        /// 半径
        /// </summary>
        [SerializeField]
        [Header("半径")]
        [Range(1.0f, 5.0f)]
        protected float m_Radius = 3.0f;

        /// <summary>
        /// 相对关节2D
        /// </summary>
        [SerializeField]
        [Header("相对关节2D")]
        private RelativeJoint2D m_RelativeJoint2D = default;

        /// <summary>
        /// 碰撞盒大小
        /// </summary>
        private Vector2 m_Size;

        /// <summary>
        /// 对角线角度
        /// </summary>
        private float[] m_DiagonalAngles = new float[4];
        #endregion

        #region Functioon
        /// <summary>
        /// 显示
        /// </summary>
        /// <param name="centerRadius">中心节点半径</param>
        /// <param name="angle">角度</param>
        public virtual void Show(float centerRadius, float angle = 0.0f)
        {
            //计算对角线角度
            BoxCollider2D boxCollider2D = this.transform.GetComponent<BoxCollider2D>();
            this.m_Size = boxCollider2D.size;
            this.m_DiagonalAngles = new float[4];
            this.m_DiagonalAngles[0] = Mathf.Atan2(this.m_Size.y * 0.5f, this.m_Size.x * 0.5f) * Mathf.Rad2Deg;
            this.m_DiagonalAngles[1] = Mathf.Atan2(this.m_Size.y * 0.5f, -this.m_Size.x * 0.5f) * Mathf.Rad2Deg;
            this.m_DiagonalAngles[2] = Mathf.Atan2(-this.m_Size.y * 0.5f, -this.m_Size.x * 0.5f) * Mathf.Rad2Deg + 360.0f;
            this.m_DiagonalAngles[3] = Mathf.Atan2(-this.m_Size.y * 0.5f, this.m_Size.x * 0.5f) * Mathf.Rad2Deg + 360.0f;

            //重映射角度
            angle += 180.0f;
            angle %= 360.0f;
            //计算混合距离
            float innerLength = this.GetInterLength(angle);
            float length = innerLength + this.m_Radius + centerRadius;
            float x = length * Mathf.Cos(angle * Mathf.Deg2Rad);
            float y = length * Mathf.Sin(angle * Mathf.Deg2Rad);
            this.m_RelativeJoint2D.linearOffset = new Vector2(x, y);

            this.gameObject.SetActive(true);
        }

        /// <summary>
        /// 隐藏
        /// </summary>
        /// <param name="exit">是否是整体退出</param>
        public virtual void Hide(bool exit = false)
        {
            this.m_RelativeJoint2D.linearOffset = Vector2.zero;
            this.transform.localPosition = Vector3.zero;
            this.gameObject.SetActive(false);
        }

        /// <summary>
        /// 获取矩形内部长度
        /// </summary>
        /// <param name="angle">当前角度</param>
        /// <returns>矩形内部长度</returns>
        private float GetInterLength(float angle)
        {
            float innerLength = 0;
            if (angle <= this.m_DiagonalAngles[0])
            {
                float x = this.m_Size.x * 0.5f;
                float y = Mathf.Tan(angle * Mathf.Deg2Rad) * x;
                innerLength = Mathf.Sqrt(x * x + y * y);
            }
            else if (angle <= this.m_DiagonalAngles[1])
            {
                float y = this.m_Size.y * 0.5f;
                float x = y / Mathf.Tan(angle * Mathf.Deg2Rad);
                innerLength = Mathf.Sqrt(x * x + y * y);
            }
            else if (angle <= this.m_DiagonalAngles[2])
            {
                float x = this.m_Size.x * 0.5f;
                float y = Mathf.Tan(angle * Mathf.Deg2Rad) * x;
                innerLength = Mathf.Sqrt(x * x + y * y);
            }
            else if (angle <= this.m_DiagonalAngles[3])
            {
                float y = this.m_Size.y * 0.5f;
                float x = y / Mathf.Tan(angle * Mathf.Deg2Rad);
                innerLength = Mathf.Sqrt(x * x + y * y);
            }
            else
            {
                float x = this.m_Size.x * 0.5f;
                float y = Mathf.Tan(angle * Mathf.Deg2Rad) * x;
                innerLength = Mathf.Sqrt(x * x + y * y);
            }
            return innerLength;
        }
        #endregion
    }
}